{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "2b9582dc",
   "metadata": {},
   "source": [
    "# SingleStoreDB\n",
    ">[SingleStoreDB](https://singlestore.com/) is a high-performance distributed SQL database that supports deployment both in the [cloud](https://www.singlestore.com/cloud/) and on-premises. It provides vector storage, and vector functions including [dot_product](https://docs.singlestore.com/managed-service/en/reference/sql-reference/vector-functions/dot_product.html) and [euclidean_distance](https://docs.singlestore.com/managed-service/en/reference/sql-reference/vector-functions/euclidean_distance.html), thereby supporting AI applications that require text similarity matching. \n",
    "\n",
    "This tutorial illustrates how to [work with vector data in SingleStoreDB](https://docs.singlestore.com/managed-service/en/developer-resources/functional-extensions/working-with-vector-data.html)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e4a61a4d",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Establishing a connection to the database is facilitated through the singlestoredb Python connector.\n",
    "# Please ensure that this connector is installed in your working environment.\n",
    "%pip install --upgrade --quiet  singlestoredb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39a0132a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import getpass\n",
    "import os\n",
    "\n",
    "# We want to use OpenAIEmbeddings so we have to get the OpenAI API Key.\n",
    "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6104fde8",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.document_loaders import TextLoader\n",
    "from langchain_community.vectorstores import SingleStoreDB\n",
    "from langchain_openai import OpenAIEmbeddings\n",
    "from langchain_text_splitters import CharacterTextSplitter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7b45113c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load text samples\n",
    "loader = TextLoader(\"../../modules/state_of_the_union.txt\")\n",
    "documents = loader.load()\n",
    "text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)\n",
    "docs = text_splitter.split_documents(documents)\n",
    "\n",
    "embeddings = OpenAIEmbeddings()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "535b2687",
   "metadata": {},
   "source": [
    "There are several ways to establish a [connection](https://singlestoredb-python.labs.singlestore.com/generated/singlestoredb.connect.html) to the database. You can either set up environment variables or pass named parameters to the `SingleStoreDB constructor`. Alternatively, you may provide these parameters to the `from_documents` and `from_texts` methods."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0b316bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Setup connection url as environment variable\n",
    "os.environ[\"SINGLESTOREDB_URL\"] = \"root:pass@localhost:3306/db\"\n",
    "\n",
    "# Load documents to the store\n",
    "docsearch = SingleStoreDB.from_documents(\n",
    "    docs,\n",
    "    embeddings,\n",
    "    table_name=\"notebook\",  # use table with a custom name\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0eaa4297",
   "metadata": {},
   "outputs": [],
   "source": [
    "query = \"What did the president say about Ketanji Brown Jackson\"\n",
    "docs = docsearch.similarity_search(query)  # Find documents that correspond to the query\n",
    "print(docs[0].page_content)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "035cba66",
   "metadata": {},
   "source": [
    "Enhance your search efficiency with SingleStore DB version 8.5 or above by leveraging [ANN vector indexes](https://docs.singlestore.com/cloud/reference/sql-reference/vector-functions/vector-indexing/). By setting `use_vector_index=True` during vector store object creation, you can activate this feature. Additionally, if your vectors differ in dimensionality from the default OpenAI embedding size of 1536, ensure to specify the `vector_size` parameter accordingly. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "86efff90",
   "metadata": {},
   "source": [
    "## Multi-modal Example: Leveraging CLIP and OpenClip Embeddings\n",
    "\n",
    "In the realm of multi-modal data analysis, the integration of diverse information types like images and text has become increasingly crucial. One powerful tool facilitating such integration is [CLIP](https://openai.com/research/clip), a cutting-edge model capable of embedding both images and text into a shared semantic space. By doing so, CLIP enables the retrieval of relevant content across different modalities through similarity search.\n",
    "\n",
    "To illustrate, let's consider an application scenario where we aim to effectively analyze multi-modal data. In this example, we harness the capabilities of [OpenClip multimodal embeddings](https://python.langchain.com/docs/integrations/text_embedding/open_clip), which leverage CLIP's framework. With OpenClip, we can seamlessly embed textual descriptions alongside corresponding images, enabling comprehensive analysis and retrieval tasks. Whether it's identifying visually similar images based on textual queries or finding relevant text passages associated with specific visual content, OpenClip empowers users to explore and extract insights from multi-modal data with remarkable efficiency and accuracy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c0bce88",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install -U langchain openai singlestoredb langchain-experimental # (newest versions required for multi-modal)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "21a8c25c",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from langchain_community.vectorstores import SingleStoreDB\n",
    "from langchain_experimental.open_clip import OpenCLIPEmbeddings\n",
    "\n",
    "os.environ[\"SINGLESTOREDB_URL\"] = \"root:pass@localhost:3306/db\"\n",
    "\n",
    "TEST_IMAGES_DIR = \"../../modules/images\"\n",
    "\n",
    "docsearch = SingleStoreDB(OpenCLIPEmbeddings())\n",
    "\n",
    "image_uris = sorted(\n",
    "    [\n",
    "        os.path.join(TEST_IMAGES_DIR, image_name)\n",
    "        for image_name in os.listdir(TEST_IMAGES_DIR)\n",
    "        if image_name.endswith(\".jpg\")\n",
    "    ]\n",
    ")\n",
    "\n",
    "# Add images\n",
    "docsearch.add_images(uris=image_uris)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
